.TH std::defer_lock,std::try_to_lock,std::adopt_lock 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::defer_lock,std::try_to_lock,std::adopt_lock \- std::defer_lock,std::try_to_lock,std::adopt_lock

.SH Synopsis
   Defined in header <mutex>
   constexpr std::defer_lock_t defer_lock {};           \fI(since C++11)\fP
                                                        \fI(until C++17)\fP
   inline constexpr std::defer_lock_t defer_lock {};    \fI(since C++17)\fP
   constexpr std::try_to_lock_t try_to_lock {};         \fI(since C++11)\fP
                                                        \fI(until C++17)\fP
   inline constexpr std::try_to_lock_t try_to_lock {};  \fI(since C++17)\fP
   constexpr std::adopt_lock_t adopt_lock {};           \fI(since C++11)\fP
                                                        \fI(until C++17)\fP
   inline constexpr std::adopt_lock_t adopt_lock {};    \fI(since C++17)\fP

   std::defer_lock, std::try_to_lock and std::adopt_lock are instances of empty struct
   tag types std::defer_lock_t, std::try_to_lock_t and std::adopt_lock_t respectively.

   They are used to specify locking strategies for std::lock_guard, std::unique_lock
   and std::shared_lock.

   Type          Effect(s)
   defer_lock_t  do not acquire ownership of the mutex
   try_to_lock_t try to acquire ownership of the mutex without blocking
   adopt_lock_t  assume the calling thread already has ownership of the mutex

.SH Example



// Run this code

 #include <iostream>
 #include <mutex>
 #include <thread>

 struct bank_account
 {
     explicit bank_account(int balance) : balance{balance} {}
     int balance;
     std::mutex m;
 };

 void transfer(bank_account& from, bank_account& to, int amount)
 {
     if (&from == &to) // avoid deadlock in case of self transfer
         return;

     // lock both mutexes without deadlock
     std::lock(from.m, to.m);
     // make sure both already-locked mutexes are unlocked at the end of scope
     std::lock_guard lock1{from.m, std::adopt_lock};
     std::lock_guard lock2{to.m, std::adopt_lock};

 // equivalent approach:
 //  std::unique_lock<std::mutex> lock1{from.m, std::defer_lock};
 //  std::unique_lock<std::mutex> lock2{to.m, std::defer_lock};
 //  std::lock(lock1, lock2);

     from.balance -= amount;
     to.balance += amount;
 }

 int main()
 {
     bank_account my_account{100};
     bank_account your_account{50};

     std::thread t1{transfer, std::ref(my_account), std::ref(your_account), 10};
     std::thread t2{transfer, std::ref(your_account), std::ref(my_account), 5};

     t1.join();
     t2.join();

     std::cout << "my_account.balance = " << my_account.balance << "\\n"
                  "your_account.balance = " << your_account.balance << '\\n';
 }

.SH Output:

 my_account.balance = 95
 your_account.balance = 55

.SH See also

   defer_lock_t
   try_to_lock_t
   adopt_lock_t  tag type used to specify locking strategy
   \fI(C++11)\fP       \fI(class)\fP
   \fI(C++11)\fP
   \fI(C++11)\fP
   constructor   constructs a lock_guard, optionally locking the given mutex
                 \fI(public member function of std::lock_guard<Mutex>)\fP
                 constructs a unique_lock, optionally locking (i.e., taking ownership
   constructor   of) the supplied mutex
                 \fI(public member function of std::unique_lock<Mutex>)\fP
